package com.xli.module.framemoduleright.controller;

import com.xli.dto.component.SelectItem;
import com.xli.dto.component.TreeNode;
import com.xli.dto.component.model.TableTreeModel;
import com.xli.dto.component.model.TreeModel;
import com.xli.dto.component.util.TreeUtil;
import com.xli.dto.controller.BaseController;
import com.xli.dto.result.ResultVO;
import com.xli.dto.result.status.Status;
import com.xli.dto.validation.group.IGroup;
import com.xli.module.framemodule.entity.dto.ModuleSearchDTO;
import com.xli.module.framemodule.entity.mapper.IFrameModuleMapper;
import com.xli.module.framemodule.entity.vo.ModuleVO;
import com.xli.module.framemoduleright.entity.dto.ModuleRightDTO;
import com.xli.module.framemoduleright.entity.vo.ModuleRightVO;
import com.xli.module.framemoduleright.entity.vo.ModuleUserVO;
import com.xli.organ.ou.frameou.entity.FrameOu;
import com.xli.organ.ou.frameou.service.IFrameOuService;
import com.xli.organ.role.framerole.entity.FrameRole;
import com.xli.organ.role.framerole.service.IFrameRoleService;
import com.xli.organ.user.frameuser.entity.FrameUser;
import com.xli.organ.user.frameuser.service.IFrameUserService;
import com.xli.ui.module.framemodule.entity.FrameModule;
import com.xli.ui.module.framemodule.service.IFrameModuleService;
import com.xli.ui.module.framemodulerole.entity.FrameModuleRole;
import com.xli.ui.module.framemodulerole.service.IFrameModuleRoleService;
import com.xli.ui.module.framemoduleuser.entity.FrameModuleUser;
import com.xli.ui.module.framemoduleuser.service.IFrameModuleUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Tag(name = "模块授权")
@RestController
@RequestMapping("/frameModuleRight")
public class FrameModuleRightController extends BaseController {

    @Autowired
    IFrameModuleUserService iFrameModuleUserService;
    @Autowired
    IFrameModuleRoleService iFrameModuleRoleService;
    @Autowired
    IFrameModuleService iFrameModuleService;
    @Autowired
    IFrameRoleService iFrameRoleService;
    @Autowired
    IFrameOuService iFrameOuService;
    @Autowired
    IFrameUserService iFrameUserService;

    @Operation(summary = "新增授权")
    @PostMapping(value = "/add")
    public ResultVO<String> add(@RequestBody @Validated(IGroup.add.class) ModuleRightDTO dto) {
        List<FrameModule> frameModuleList = new ArrayList<>();
        if (dto.isAuthChild()) {
            //查出本级模块，和所有子模块
            frameModuleList = iFrameModuleService.findModuleListById(Long.valueOf(dto.getModuleId()));
        } else {
            //仅本级
            frameModuleList.add(iFrameModuleService.find(Long.valueOf(dto.getModuleId())));
        }
        for (FrameModule frameModule : frameModuleList) {
            List<FrameModuleRole> frameModuleRoleList = iFrameModuleRoleService.findModuleRoleListByModuleId(frameModule.getId());
            List<FrameModuleUser> frameModuleUserList = iFrameModuleUserService.findModuleUserListByModuleId(frameModule.getId());
            //该模块已存在的角色
            Set<String> roleIds = frameModuleRoleList.stream()
                    .map(frameModuleRole -> frameModuleRole.getRole_id().toString())
                    .collect(Collectors.toSet());
            Set<String> userIds = frameModuleUserList.stream()
                    .map(frameModuleUser -> frameModuleUser.getUser_id().toString())
                    .collect(Collectors.toSet());


            //被去掉了，要删除
            List<String> delRoleIdList = roleIds.stream()
                    .filter(id -> !dto.getRoleIds().contains(id))
                    .toList();
            List<String> delUserIdList = userIds.stream()
                    .filter(id -> !dto.getUserIds().contains(id))
                    .toList();

            //新加的
            List<String> addRoleIdList = dto.getRoleIds().stream()
                    .filter(id -> !roleIds.contains(id))
                    .toList();
            List<String> addUserIdList = dto.getUserIds().stream()
                    .filter(id -> !userIds.contains(id))
                    .toList();

            iFrameModuleRoleService.insert(frameModule.getId(), addRoleIdList);
            if (!delRoleIdList.isEmpty()) {
                iFrameModuleRoleService.delete(frameModule.getId(), delRoleIdList);
            }
            iFrameModuleUserService.insert(frameModule.getId(), addUserIdList);
            if (!delUserIdList.isEmpty()) {
                iFrameModuleUserService.delete(frameModule.getId(), delUserIdList);
            }
        }
        return new ResultVO<>(Status.SUCCESS, "添加成功");
    }

    @Operation(summary = "查询列表")
    @PostMapping(value = "/search")
    public ResultVO<TableTreeModel<ModuleVO, FrameModule, ModuleSearchDTO>> search(@RequestBody @Validated(IGroup.search.class) ModuleSearchDTO dto) {

        TableTreeModel<ModuleVO, FrameModule, ModuleSearchDTO> tableModel = new TableTreeModel<>(dto) {

            @Override
            public List<TreeNode<ModuleVO>> fetch(int current, int pageSize) {
                return getTreeNodeList(Long.valueOf(dto.getPid()));
            }

            @Override
            public List<TreeNode<ModuleVO>> fetchChild(TreeNode<ModuleVO> treeNode) {
                return getTreeNodeList(treeNode.getId());
            }

            private List<TreeNode<ModuleVO>> getTreeNodeList(Long pid) {
                List<FrameModule> frameModuleList = iFrameModuleService.findModuleListByPid(pid);
                return frameModuleList.stream().map(frameModule -> {
                    TreeNode<ModuleVO> treeNode = new TreeNode<>();
                    treeNode.setId(frameModule.getId());
                    treeNode.setPid(frameModule.getPid());
                    treeNode.setText(frameModule.getName());
                    treeNode.setVo(IFrameModuleMapper.INSTANCE.toVO(frameModule));
                    return treeNode;
                }).collect(Collectors.toList());
            }
        };
        return new ResultVO<>(Status.SUCCESS, "查询成功", tableModel);
    }

    @Operation(summary = "查询详情")
    @PostMapping(value = "/detail/{id}")
    public ResultVO<ModuleRightVO> detail(@PathVariable("id") @NotBlank(message = "id必填") String moduleId) {
        List<FrameModuleRole> frameModuleRoleList = iFrameModuleRoleService.findModuleRoleListByModuleId(Long.valueOf(moduleId));
        List<FrameModuleUser> frameModuleUserList = iFrameModuleUserService.findModuleUserListByModuleId(Long.valueOf(moduleId));
        ModuleRightVO moduleRightVO = new ModuleRightVO();
        moduleRightVO.setModuleId(moduleId);
        moduleRightVO.setRoleIds(frameModuleRoleList.stream()
                .map(frameModuleRole -> frameModuleRole.getRole_id().toString())
                .collect(Collectors.toList()));
        moduleRightVO.setUserIds(frameModuleUserList.stream()
                .map(frameModuleUser -> frameModuleUser.getUser_id().toString())
                .collect(Collectors.toList()));
        return new ResultVO<>(Status.FAILED, "查询成功", moduleRightVO);
    }

    @PostMapping(value = "/getRoleModel/{id}")
    public ResultVO<List<SelectItem>> getRoleModel(@PathVariable("id") @NotBlank(message = "id必填") String moduleId) {
        List<SelectItem> selectItemList = new ArrayList<>();
        List<FrameRole> roleList = iFrameRoleService.findAllRoleList();
        if (roleList != null && !roleList.isEmpty()) {
            List<FrameModuleRole> frameModuleRoleList = iFrameModuleRoleService.findModuleRoleListByModuleId(Long.valueOf(moduleId));
            List<Long> roleIdList = frameModuleRoleList.stream()
                    .map(FrameModuleRole::getRole_id)
                    .toList();
            for (FrameRole role : roleList) {
                SelectItem selectItem = new SelectItem();
                selectItem.setId(String.valueOf(role.getId()));
                selectItem.setText(role.getRole_name());
                selectItem.setSelected(roleIdList.contains(role.getId()));
                selectItemList.add(selectItem);
            }
        }
        return new ResultVO<>(Status.SUCCESS, "查询成功", selectItemList);
    }

    @PostMapping(value = "/getUserTreeModel/{id}")
    public ResultVO<TreeModel<ModuleUserVO>> getUserTreeModel(@PathVariable("id") @NotBlank(message = "id必填") String moduleId) {
        List<FrameModuleUser> frameModuleUserList = iFrameModuleUserService.findModuleUserListByModuleId(Long.valueOf(moduleId));
        Set<Long> userIdList = frameModuleUserList.stream().map(FrameModuleUser::getUser_id).collect(Collectors.toSet());

        TreeModel<ModuleUserVO> treeModel = new TreeModel<>() {

            @Override
            public List<TreeNode<ModuleUserVO>> fetch() {
                return getOuTreeNodeList(TreeUtil.defaultPid);
            }

            @Override
            public List<TreeNode<ModuleUserVO>> fetchChild(TreeNode<ModuleUserVO> treeNode) {
                List<TreeNode<ModuleUserVO>> treeNodeList = new ArrayList<>();
                treeNodeList.addAll(getOuTreeNodeList(treeNode.getId()));
                treeNodeList.addAll(getUserTreeNodeList(treeNode.getId()));
                return treeNodeList;
            }

            private List<TreeNode<ModuleUserVO>> getOuTreeNodeList(Long pid) {
                List<FrameOu> frameOuList = iFrameOuService.findOuListByPid(pid);
                return frameOuList.stream().map(frameOu -> {
                    TreeNode<ModuleUserVO> treeNode = new TreeNode<>();
                    treeNode.setId(frameOu.getId());
                    treeNode.setPid(frameOu.getPid());
                    treeNode.setText(frameOu.getOu_name());
                    treeNode.setShowCheckbox(false);
                    return treeNode;
                }).collect(Collectors.toList());
            }

            private List<TreeNode<ModuleUserVO>> getUserTreeNodeList(Long ouId) {
                List<FrameUser> frameUserList = iFrameUserService.findUserListByOu(ouId);
                return frameUserList.stream().map(frameUser -> {
                    TreeNode<ModuleUserVO> treeNode = new TreeNode<>();
                    treeNode.setId(frameUser.getId());
                    treeNode.setPid(frameUser.getOu_id());
                    treeNode.setText(frameUser.getUsername());
                    treeNode.setShowCheckbox(true);
                    treeNode.setSelected(userIdList.contains(frameUser.getId()));
                    return treeNode;
                }).collect(Collectors.toList());
            }
        };
        return new ResultVO<>(Status.SUCCESS, "查询成功", treeModel);
    }
}
